#include "BvhNode.h"
#include <algorithm>
#include "Utility.h"
#include <iostream>
namespace RayTracer
{
	inline BvhNode::BvhNode() { }

	BvhNode::BvhNode(const std::vector<std::shared_ptr<Hitable>>& src_objects, size_t start, size_t end, float time0, float time1)
	{
		/*auto objects = src_objects;

		int axis = RandomInt(0, 2);
		auto comparator =
			(axis == 0) ? box_x_compare : (axis == 1)
			? box_y_compare : box_z_compare;

		size_t object_span = end - start;

		if (object_span == 1) 
		{
			left = right = objects[start];
		}
		else if (object_span == 2) 
		{
			if ((this->*comparator)(objects[start], objects[start + 1])) 
			{
				left = objects[start];
				right = objects[start + 1];
			}
			else 
			{
				left = objects[start + 1];
				right = objects[start];
			}
		}
		else {
			std::sort(objects.begin() + start, objects.begin() + end, comparator);

			auto mid = start + object_span / 2;
			left = std::make_shared<BvhNode>(objects, start, mid, time0, time1);
			right = std::make_shared<BvhNode>(objects, mid, end, time0, time1);
		}

		AABB box_left, box_right;

		if (!left->BoundingBox(time0, time1, box_left)
			|| !right->BoundingBox(time0, time1, box_right))
		{
			std::cout << "No bounding box in bvh_node constructor.\n";
			assert(false);
		}

		box = AABB::SurroundingBox(box_left, box_right);*/
	}

	bool BvhNode::Hit(const Ray & r, float t_min, float t_max, HitRecord & rec) const
	{
		if (!box.Hit(r, t_min, t_max))
			return false;

		bool hit_left = left->Hit(r, t_min, t_max, rec);
		bool hit_right = right->Hit(r, t_min, hit_left ? rec.t : t_max, rec);

		return hit_left || hit_right;
	}

	bool BvhNode::BoundingBox(AABB& output_box) const 
	{
		output_box = box;
		return true;
	}
}